package com.ps.service.setting.imp;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;

import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;


import com.ps.dao.BaseDaoSupport;
import com.ps.dao.person.EmployeeDAO;
import com.ps.dao.setting.PermissionDAO;
import com.ps.dao.setting.RoleDAO;
import com.ps.dao.setting.RoleOfPermissionDAO;
import com.ps.entity.Result;
import com.ps.entity.Status;
import com.ps.entity.setting.RoleDetail;
import com.ps.global.Globals;
import com.ps.pojo.person.Employee;
import com.ps.pojo.setting.Permission;
import com.ps.pojo.setting.Role;
import com.ps.pojo.setting.RoleOfPermission;
import com.ps.service.BaseServiceSupport;
import com.ps.service.setting.RoleService;
import com.ps.util.Kit;
import com.ps.util.R;

public class RoleServiceImp extends BaseServiceSupport<Role> implements RoleService {

	
	@Autowired
    private RoleDAO roleDao;
   
    @Autowired
    private RoleOfPermissionDAO roleOfPermissionDAO;
	
    @Autowired
    private EmployeeDAO employeeDAO;
    
    @Autowired
    private PermissionDAO permissionDAO;
    
	public Result addRole(Role role, List<Integer> permissionIds) {
        Result result = Kit.createResult();
        Session session = null;
        Transaction tx = null;
		try {
			session = roleDao.getSessionFactory().openSession();
			tx = session.beginTransaction();
			session.save(role);
			for (Integer pid : permissionIds) {
				RoleOfPermission rop = new RoleOfPermission();
				rop.setRoleId(role.getRoleId());
				rop.setPermissionId(pid);
				rop.setInputerId(role.getInputerId());
				rop.setInTime(new Timestamp(System.currentTimeMillis()));
				session.save(rop);
			}
			tx.commit();
			session.close();
/*			Integer id = roleDao.save(role);
			for (Integer pid : permissionIds) {
				RoleOfPermission rop = new RoleOfPermission();
				rop.setRoleId(id);
				rop.setPermissionId(pid);
				rop.setInputerId(role.getInputerId());
				rop.setInTime(new Timestamp(System.currentTimeMillis()));
				roleOfPermissionDAO.save(rop);
			}*/
			result.getStatus().setMessage(R.string.getProperty("addsucces"));
			result.setDatas(role.getRoleId());
		} catch (Exception e) {
			if (tx != null) tx.rollback();
		
			if (session != null) session.close();
			log.error("addRole exception ", e);
			result.getStatus().setCode(Status.FAIL);
			result.getStatus().setMessage(R.string.getProperty("addfail"));
		}		
		return result;
	}

	public Result updateRole(Role role, List<Integer> permissionIds) {
        Result result = Kit.createResult();
        Session session = null;
        Transaction tx = null;
		try {
			session = roleDao.getSessionFactory().openSession();
			tx = session.beginTransaction();
			session.update(role); 
			String hql = "DELETE RoleOfPermission WHERE roleId = ?";
			Query query = session.createQuery(hql);
			query.setInteger(0, role.getRoleId());
			query.executeUpdate();
			for (Integer pid : permissionIds) {
				RoleOfPermission rop = new RoleOfPermission();
				rop.setRoleId(role.getRoleId());
				rop.setPermissionId(pid);
				rop.setInputerId(role.getInputerId());
				rop.setInTime(new Timestamp(System.currentTimeMillis()));
				session.save(rop);
			}
			tx.commit();
			session.close();
			result.getStatus().setMessage(R.string.getProperty("updsucces"));
			result.setDatas(role.getRoleId());
		} catch (Exception e) {
			if (tx != null) tx.rollback();
			if (session != null) session.close();
			log.error("updateRole exception ", e);
			result.getStatus().setCode(Status.FAIL);
			result.getStatus().setMessage(R.string.getProperty("updfail"));
		}		
		return result;		
	}

	public Result deleteRole(Integer roleId) {
        Result result = Kit.createResult();
        Session session = null;
        Transaction tx = null;
		try {
			session = roleDao.getSessionFactory().openSession();
			tx = session.beginTransaction();

			String hql = "DELETE RoleOfPermission WHERE roleId = ?";
			Query query = session.createQuery(hql);
			query.setInteger(0, roleId);
			query.executeUpdate();
			hql = "DELETE Role WHERE roleId = ?";
			query = session.createQuery(hql);
			query.setInteger(0, roleId);
			query.executeUpdate();
			tx.commit();
			session.close();
			result.getStatus().setMessage(R.string.getProperty("updsucces"));
			result.setDatas(roleId);
		} catch (Exception e) {
			if (tx != null) tx.rollback();
			if (session != null) session.close();
			log.error("updateRole exception ", e);
			result.getStatus().setCode(Status.FAIL);
			result.getStatus().setMessage(R.string.getProperty("updfail"));
		}		
		return result;	
	}
	
	public Result queryRoleDetail(Integer roleId) {
		Result result = Kit.createResult();
		try {
			Role role = roleDao.findById(roleId);
			List<RoleOfPermission> roleOfPermissions = roleOfPermissionDAO.findByProperty(RoleOfPermissionDAO.ROLE_ID, roleId);
			List<Permission> permissions = new ArrayList<Permission>();
			for (RoleOfPermission rop : roleOfPermissions) {
				Permission p = permissionDAO.findById(rop.getPermissionId());
				permissions.add(p);
			}
			String inputer = "admin";
			//Employee employee = employeeDAO.findById(role.getInputerId()) ;
			//if (employee != null) inputer = employee.getName();
			
			if (role != null){
				RoleDetail roleDetail = new RoleDetail(role,inputer,
						permissions);
				result.setDatas(roleDetail);
			} else {
				result.getStatus().setCode(Status.EMPTY);
				result.getStatus().setMessage(R.string.getProperty("queryempty"));
			}
			
		} catch (Exception e) {
			log.error("queryRoleDetail exception ", e);
			result.getStatus().setCode(Status.FAIL);
			result.getStatus().setMessage(R.string.getProperty("queryfail"));
		} 
		
		return result;
	}
	
	
	
	
	
	public Result findManagerRole() {
		DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Role.class);
    	detachedCriteria.add(Restrictions.ne("roleId", Globals.NORMAL_ROLE_ID));
    	detachedCriteria.add(Restrictions.ne("roleId", Globals.ADMIN_ROLE_ID));
    	detachedCriteria.addOrder(Order.asc("roleId"));
		return this.findByCriteria(detachedCriteria);
	}    	
	
	
	@Override
	public BaseDaoSupport<Role> getBaseDao() {
		// TODO Auto-generated method stub
		return roleDao;
	}

	public Set<Integer> queryPermissionIdsByRoleId(Integer roleId) {
		try {
			List<RoleOfPermission> roleOfPermissions = roleOfPermissionDAO.findByProperty(RoleOfPermissionDAO.ROLE_ID, roleId);
			
			if (roleOfPermissions != null && roleOfPermissions.size() > 0) {
				Set<Integer> permissions = new HashSet<Integer>();
				for (RoleOfPermission rop : roleOfPermissions) {
					permissions.add(rop.getPermissionId());
				}
				return permissions;
			}
			
			
		} catch (Exception e) {
			log.error("queryPermissionIdsByRoleId exception ", e);
		}
		return null;
	}




}
